home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / sunrpc / rpc_scan.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  8KB  |  474 lines

  1. /* @(#)rpc_scan.c    2.1 88/08/01 4.0 RPCSRC */
  2. /*
  3.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  4.  * unrestricted use provided that this legend is included on all tape
  5.  * media and as a part of the software program in whole or part.  Users
  6.  * may copy or modify Sun RPC without charge, but are not authorized
  7.  * to license or distribute it to anyone else except as part of a product or
  8.  * program developed by the user.
  9.  * 
  10.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13.  * 
  14.  * Sun RPC is provided with no support and without any obligation on the
  15.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  16.  * modification or enhancement.
  17.  * 
  18.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20.  * OR ANY PART THEREOF.
  21.  * 
  22.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23.  * or profits or other special, indirect and consequential damages, even if
  24.  * Sun has been advised of the possibility of such damages.
  25.  * 
  26.  * Sun Microsystems, Inc.
  27.  * 2550 Garcia Avenue
  28.  * Mountain View, California  94043
  29.  */
  30. #ifndef lint
  31. static char sccsid[] = "@(#)rpc_scan.c 1.6 87/06/24 (C) 1987 SMI";
  32. #endif
  33.  
  34. /*
  35.  * rpc_scan.c, Scanner for the RPC protocol compiler 
  36.  * Copyright (C) 1987, Sun Microsystems, Inc. 
  37.  */
  38. #include <stdio.h>
  39. #include <ctype.h>
  40. #include <strings.h>
  41. #include "rpc_scan.h"
  42. #include "rpc_util.h"
  43.  
  44. #define startcomment(where) (where[0] == '/' && where[1] == '*')
  45. #define endcomment(where) (where[-1] == '*' && where[0] == '/')
  46.  
  47. static int pushed = 0;    /* is a token pushed */
  48. static token lasttok;    /* last token, if pushed */
  49.  
  50. /*
  51.  * scan expecting 1 given token 
  52.  */
  53. void
  54. scan(expect, tokp)
  55.     tok_kind expect;
  56.     token *tokp;
  57. {
  58.     get_token(tokp);
  59.     if (tokp->kind != expect) {
  60.         expected1(expect);
  61.     }
  62. }
  63.  
  64. /*
  65.  * scan expecting 2 given tokens 
  66.  */
  67. void
  68. scan2(expect1, expect2, tokp)
  69.     tok_kind expect1;
  70.     tok_kind expect2;
  71.     token *tokp;
  72. {
  73.     get_token(tokp);
  74.     if (tokp->kind != expect1 && tokp->kind != expect2) {
  75.         expected2(expect1, expect2);
  76.     }
  77. }
  78.  
  79. /*
  80.  * scan expecting 3 given token 
  81.  */
  82. void
  83. scan3(expect1, expect2, expect3, tokp)
  84.     tok_kind expect1;
  85.     tok_kind expect2;
  86.     tok_kind expect3;
  87.     token *tokp;
  88. {
  89.     get_token(tokp);
  90.     if (tokp->kind != expect1 && tokp->kind != expect2
  91.         && tokp->kind != expect3) {
  92.         expected3(expect1, expect2, expect3);
  93.     }
  94. }
  95.  
  96.  
  97. /*
  98.  * scan expecting a constant, possibly symbolic 
  99.  */
  100. void
  101. scan_num(tokp)
  102.     token *tokp;
  103. {
  104.     get_token(tokp);
  105.     switch (tokp->kind) {
  106.     case TOK_IDENT:
  107.         break;
  108.     default:
  109.         error("constant or identifier expected");
  110.     }
  111. }
  112.  
  113.  
  114. /*
  115.  * Peek at the next token 
  116.  */
  117. void
  118. peek(tokp)
  119.     token *tokp;
  120. {
  121.     get_token(tokp);
  122.     unget_token(tokp);
  123. }
  124.  
  125.  
  126. /*
  127.  * Peek at the next token and scan it if it matches what you expect 
  128.  */
  129. int
  130. peekscan(expect, tokp)
  131.     tok_kind expect;
  132.     token *tokp;
  133. {
  134.     peek(tokp);
  135.     if (tokp->kind == expect) {
  136.         get_token(tokp);
  137.         return (1);
  138.     }
  139.     return (0);
  140. }
  141.  
  142.  
  143.  
  144. /*
  145.  * Get the next token, printing out any directive that are encountered. 
  146.  */
  147. void
  148. get_token(tokp)
  149.     token *tokp;
  150. {
  151.     int commenting;
  152.  
  153.     if (pushed) {
  154.         pushed = 0;
  155.         *tokp = lasttok;
  156.         return;
  157.     }
  158.     commenting = 0;
  159.     for (;;) {
  160.         if (*where == 0) {
  161.             for (;;) {
  162.                 if (!fgets(curline, MAXLINESIZE, fin)) {
  163.                     tokp->kind = TOK_EOF;
  164.                     *where = 0;
  165.                     return;
  166.                 }
  167.                 linenum++;
  168.                 if (commenting) {
  169.                     break;
  170.                 } else if (cppline(curline)) {
  171.                     docppline(curline, &linenum, 
  172.                           &infilename);
  173.                 } else if (directive(curline)) {
  174.                     printdirective(curline);
  175.                 } else {
  176.                     break;
  177.                 }
  178.             }
  179.             where = curline;
  180.         } else if (isspace(*where)) {
  181.             while (isspace(*where)) {
  182.                 where++;    /* eat */
  183.             }
  184.         } else if (commenting) {
  185.             where++;
  186.             if (endcomment(where)) {
  187.                 where++;
  188.                 commenting--;
  189.             }
  190.         } else if (startcomment(where)) {
  191.             where += 2;
  192.             commenting++;
  193.         } else {
  194.             break;
  195.         }
  196.     }
  197.  
  198.     /*
  199.      * 'where' is not whitespace, comment or directive Must be a token! 
  200.      */
  201.     switch (*where) {
  202.     case ':':
  203.         tokp->kind = TOK_COLON;
  204.         where++;
  205.         break;
  206.     case ';':
  207.         tokp->kind = TOK_SEMICOLON;
  208.         where++;
  209.         break;
  210.     case ',':
  211.         tokp->kind = TOK_COMMA;
  212.         where++;
  213.         break;
  214.     case '=':
  215.         tokp->kind = TOK_EQUAL;
  216.         where++;
  217.         break;
  218.     case '*':
  219.         tokp->kind = TOK_STAR;
  220.         where++;
  221.         break;
  222.     case '[':
  223.         tokp->kind = TOK_LBRACKET;
  224.         where++;
  225.         break;
  226.     case ']':
  227.         tokp->kind = TOK_RBRACKET;
  228.         where++;
  229.         break;
  230.     case '{':
  231.         tokp->kind = TOK_LBRACE;
  232.         where++;
  233.         break;
  234.     case '}':
  235.         tokp->kind = TOK_RBRACE;
  236.         where++;
  237.         break;
  238.     case '(':
  239.         tokp->kind = TOK_LPAREN;
  240.         where++;
  241.         break;
  242.     case ')':
  243.         tokp->kind = TOK_RPAREN;
  244.         where++;
  245.         break;
  246.     case '<':
  247.         tokp->kind = TOK_LANGLE;
  248.         where++;
  249.         break;
  250.     case '>':
  251.         tokp->kind = TOK_RANGLE;
  252.         where++;
  253.         break;
  254.  
  255.     case '"':
  256.         tokp->kind = TOK_STRCONST;
  257.         findstrconst(&where, &tokp->str);
  258.         break;
  259.  
  260.     case '-':
  261.     case '0':
  262.     case '1':
  263.     case '2':
  264.     case '3':
  265.     case '4':
  266.     case '5':
  267.     case '6':
  268.     case '7':
  269.     case '8':
  270.     case '9':
  271.         tokp->kind = TOK_IDENT;
  272.         findconst(&where, &tokp->str);
  273.         break;
  274.  
  275.  
  276.     default:
  277.         if (!(isalpha(*where) || *where == '_')) {
  278.             char buf[100];
  279.             char *p;
  280.  
  281.             s_print(buf, "illegal character in file: ");
  282.             p = buf + strlen(buf);
  283.             if (isprint(*where)) {
  284.                 s_print(p, "%c", *where);
  285.             } else {
  286.                 s_print(p, "%d", *where);
  287.             }
  288.             error(buf);
  289.         }
  290.         findkind(&where, tokp);
  291.         break;
  292.     }
  293. }
  294.  
  295.  
  296.  
  297. static
  298. unget_token(tokp)
  299.     token *tokp;
  300. {
  301.     lasttok = *tokp;
  302.     pushed = 1;
  303. }
  304.  
  305.  
  306. static
  307. findstrconst(str, val)
  308.     char **str;
  309.     char **val;
  310. {
  311.     char *p;
  312.     int size;
  313.  
  314.     p = *str;
  315.     do {
  316.         *p++;
  317.     } while (*p && *p != '"');
  318.     if (*p == 0) {
  319.         error("unterminated string constant");
  320.     }
  321.     p++;
  322.     size = p - *str;
  323.     *val = alloc(size + 1);
  324.     (void) strncpy(*val, *str, size);
  325.     (*val)[size] = 0;
  326.     *str = p;
  327. }
  328.  
  329. static
  330. findconst(str, val)
  331.     char **str;
  332.     char **val;
  333. {
  334.     char *p;
  335.     int size;
  336.  
  337.     p = *str;
  338.     if (*p == '0' && *(p + 1) == 'x') {
  339.         p++;
  340.         do {
  341.             p++;
  342.         } while (isxdigit(*p));
  343.     } else {
  344.         do {
  345.             p++;
  346.         } while (isdigit(*p));
  347.     }
  348.     size = p - *str;
  349.     *val = alloc(size + 1);
  350.     (void) strncpy(*val, *str, size);
  351.     (*val)[size] = 0;
  352.     *str = p;
  353. }
  354.  
  355.  
  356.  
  357. static token symbols[] = {
  358.               {TOK_CONST, "const"},
  359.               {TOK_UNION, "union"},
  360.               {TOK_SWITCH, "switch"},
  361.               {TOK_CASE, "case"},
  362.               {TOK_DEFAULT, "default"},
  363.               {TOK_STRUCT, "struct"},
  364.               {TOK_TYPEDEF, "typedef"},
  365.               {TOK_ENUM, "enum"},
  366.               {TOK_OPAQUE, "opaque"},
  367.               {TOK_BOOL, "bool"},
  368.               {TOK_VOID, "void"},
  369.               {TOK_CHAR, "char"},
  370.               {TOK_INT, "int"},
  371.               {TOK_UNSIGNED, "unsigned"},
  372.               {TOK_SHORT, "short"},
  373.               {TOK_LONG, "long"},
  374.               {TOK_FLOAT, "float"},
  375.               {TOK_DOUBLE, "double"},
  376.               {TOK_STRING, "string"},
  377.               {TOK_PROGRAM, "program"},
  378.               {TOK_VERSION, "version"},
  379.               {TOK_EOF, "??????"},
  380. };
  381.  
  382.  
  383. static
  384. findkind(mark, tokp)
  385.     char **mark;
  386.     token *tokp;
  387. {
  388.  
  389.     int len;
  390.     token *s;
  391.     char *str;
  392.  
  393.     str = *mark;
  394.     for (s = symbols; s->kind != TOK_EOF; s++) {
  395.         len = strlen(s->str);
  396.         if (strncmp(str, s->str, len) == 0) {
  397.             if (!isalnum(str[len]) && str[len] != '_') {
  398.                 tokp->kind = s->kind;
  399.                 tokp->str = s->str;
  400.                 *mark = str + len;
  401.                 return;
  402.             }
  403.         }
  404.     }
  405.     tokp->kind = TOK_IDENT;
  406.     for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
  407.     tokp->str = alloc(len + 1);
  408.     (void) strncpy(tokp->str, str, len);
  409.     tokp->str[len] = 0;
  410.     *mark = str + len;
  411. }
  412.  
  413. static
  414. cppline(line)
  415.     char *line;
  416. {
  417.     return (line == curline && *line == '#');
  418. }
  419.  
  420. static
  421. directive(line)
  422.     char *line;
  423. {
  424.     return (line == curline && *line == '%');
  425. }
  426.  
  427. static
  428. printdirective(line)
  429.     char *line;
  430. {
  431.     f_print(fout, "%s", line + 1);
  432. }
  433.  
  434. static
  435. docppline(line, lineno, fname)
  436.     char *line;
  437.     int *lineno;
  438.     char **fname;
  439. {
  440.     char *file;
  441.     int num;
  442.     char *p;
  443.  
  444.     line++;
  445.     while (isspace(*line)) {
  446.         line++;
  447.     }
  448.     num = atoi(line);
  449.     while (isdigit(*line)) {
  450.         line++;
  451.     }
  452.     while (isspace(*line)) {
  453.         line++;
  454.     }
  455.     if (*line != '"') {
  456.         error("preprocessor error");
  457.     }
  458.     line++;
  459.     p = file = alloc(strlen(line) + 1);
  460.     while (*line && *line != '"') {
  461.         *p++ = *line++;
  462.     }
  463.     if (*line == 0) {
  464.         error("preprocessor error");
  465.     }
  466.     *p = 0;
  467.     if (*file == 0) {
  468.         *fname = NULL;
  469.     } else {
  470.         *fname = file;
  471.     }
  472.     *lineno = num - 1;
  473. }
  474.